From f49574e42e78cff0eeeb4d00e62b875c915e9511 Mon Sep 17 00:00:00 2001 From: =?utf8?q?David=20H=C3=A4rdeman?= Date: Sat, 25 Oct 2025 15:32:06 +0200 Subject: [PATCH] odhcpd: change "-c" cmd line arg to take a dir MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit After the TZ support was added, odhcpd now reads two cfg files potentially. Instead of adding a separate switch for the system UCI file, I've changed the "-c" argument to take a directory. This is more future-proof and also serves as a preparation for the global DUID PR (which will necessitate reading from the UCI "network" file as well). While I was at it, I also made some tiny improvements to the odhcpd_reload() function to avoid an unnecessary allocation. Signed-off-by: David Härdeman Link: https://github.com/openwrt/odhcpd/pull/291 Signed-off-by: Álvaro Fernández Rojas --- src/config.c | 25 +++++++++++++++++-------- src/odhcpd.c | 20 +++++++++++++++++--- src/odhcpd.h | 3 +-- 3 files changed, 35 insertions(+), 13 deletions(-) diff --git a/src/config.c b/src/config.c index 3e916ad..7bff307 100644 --- a/src/config.c +++ b/src/config.c @@ -41,14 +41,13 @@ struct config config = { .dhcp_hostsfile = NULL, .ra_piofolder = NULL, .ra_piofolder_fd = -1, - .uci_cfgfile = "dhcp", + .uci_cfgdir = NULL, .log_level = LOG_WARNING, .log_level_cmdline = false, .log_syslog = true, }; struct sys_conf sys_conf = { - .uci_cfgfile = "system", .posix_tz = NULL, // "timezone" .posix_tz_len = 0, .tzdb_tz = NULL, // "zonename" @@ -2226,16 +2225,27 @@ void odhcpd_reload(void) { struct uci_context *uci = uci_alloc_context(); struct interface *master = NULL, *i, *tmp; + char *uci_dhcp_path = "dhcp"; + char *uci_system_path = "system"; if (!uci) return; + if (config.uci_cfgdir) { + size_t dlen = strlen(config.uci_cfgdir); + + uci_dhcp_path = alloca(dlen + sizeof("/dhcp")); + sprintf(uci_dhcp_path, "%s/dhcp", config.uci_cfgdir); + uci_system_path = alloca(dlen + sizeof("/system")); + sprintf(uci_system_path, "%s/system", config.uci_cfgdir); + } + vlist_update(&leases); avl_for_each_element(&interfaces, i, avl) clean_interface(i); struct uci_package *dhcp = NULL; - if (!uci_load(uci, config.uci_cfgfile, &dhcp)) { + if (!uci_load(uci, uci_dhcp_path, &dhcp)) { struct uci_element *e; /* 1. Global settings */ @@ -2268,9 +2278,10 @@ void odhcpd_reload(void) } ipv6_pxe_dump(); } + uci_unload(uci, dhcp); struct uci_package *system = NULL; - if (!uci_load(uci, sys_conf.uci_cfgfile, &system) && config.enable_tz == true) { + if (config.enable_tz && !uci_load(uci, uci_system_path, &system)) { struct uci_element *e; /* 1. System settings */ @@ -2280,12 +2291,12 @@ void odhcpd_reload(void) set_timezone_info_from_uci(s); } } + uci_unload(uci, system); if (config.dhcp_statefile) { - char *path = strdup(config.dhcp_statefile); + char *path = strdupa(config.dhcp_statefile); mkdir_p(dirname(path), 0755); - free(path); } if (config.ra_piofolder) { @@ -2374,8 +2385,6 @@ void odhcpd_reload(void) close_interface(i); } - uci_unload(uci, dhcp); - uci_unload(uci, system); uci_free_context(uci); } diff --git a/src/odhcpd.c b/src/odhcpd.c index 0f314bf..38d96fd 100644 --- a/src/odhcpd.c +++ b/src/odhcpd.c @@ -91,7 +91,7 @@ static void print_usage(const char *app) #endif /* EXT_CER_ID */ "\n" "\n" - " -c Use an alternative configuration file\n" + " -c Read UCI configuration files from \n" " -l Specify log level 0..7 (default %d)\n" " -f Log to stderr instead of syslog\n" " -h Print this help text and exit\n", @@ -117,9 +117,23 @@ int main(int argc, char **argv) while ((opt = getopt(argc, argv, "c:l:fh")) != -1) { switch (opt) { case 'c': - config.uci_cfgfile = realpath(optarg, NULL); - fprintf(stderr, "Configuration will be read from %s\n", config.uci_cfgfile); + struct stat sb; + char *path; + + free(config.uci_cfgdir); + config.uci_cfgdir = NULL; + + path = realpath(optarg, NULL); + if (!path || stat(path, &sb) || !S_ISDIR(sb.st_mode)) { + fprintf(stderr, "%s is not a directory, ignoring\n", optarg); + free(path); + break; + } + + fprintf(stderr, "Configuration will be read from %s\n", path); + config.uci_cfgdir = path; break; + case 'l': config.log_level = (atoi(optarg) & LOG_PRIMASK); config.log_level_cmdline = true; diff --git a/src/odhcpd.h b/src/odhcpd.h index 693da99..f2e2e74 100644 --- a/src/odhcpd.h +++ b/src/odhcpd.h @@ -194,7 +194,7 @@ struct config { char *ra_piofolder; int ra_piofolder_fd; - char *uci_cfgfile; + char *uci_cfgdir; int log_level; bool log_level_cmdline; bool log_syslog; @@ -203,7 +203,6 @@ struct config { struct sys_conf { uint8_t *posix_tz; size_t posix_tz_len; - char *uci_cfgfile; uint8_t *tzdb_tz; size_t tzdb_tz_len; }; -- 2.30.2